'---------------------------------------------------------------------------
' AVR ETHERNET I/O   -   Embedded UDP&WebServer  -   Atmega32 and RTL8019AS       	   
'---------------------------------------------------------------------------
'
'
' BASCOM-AVR IDE Version : 1.11.7.4
'
' settings: HW-stack 64. SW-stack 64. Framesize 64. Optimize code
'
' RTL8019AS, ARP, PING (var. length), HTTP, UDP, LCD and Configure
'
' Based on interrupt INT0 
'
' with PORTA relay bit 3 2 1 0  and PORTC opto bit 7 6 5 4
'
' with I2c-matrix for diagnostics
'
'
' Fusebits:
' A987:1111 = Crystal/Boden enabled
' H:      1 = JTAG disabled
' G:      0 = Preserve EEprom when chip erase
'
' Hardware:
'
' PA0 - SD0 - Databus
' PA1 - SD1
' PA2 - SD2
' PA3 - SD3
' PA4 - SD4
' PA5 - SD5
' PA6 - SD6
' PA7 - SD7

' PB0 - SA0 - Addressbus
' PB1 - SA1
' PB2 - SA2
' PB3 - SA3
' PB4 - SA4
' PB5 - MOSI
' PB6 - MISO
' PB7 - SCK

' PC0 - I2c SLC
' PC1 - I2c SDA
' PC2 - PC2
' PC3 - PC3
' PC4 - PC4
' PC5 - PC5
' PC6 - PC6
' PC7 - PC7

' PD0 - RXD
' PD1 - TXD
' PD2 - INT0
' PD3 - LE - Latch Enable
' PD4 - RSTDRV
' PD5 - EEDO
' PD6 - IORB
' PD7 - IOWB

' In the EEPROM:
'
' 00 = left blank (&hFF)
' 01 = IP-number msb
' 02 = IP-number
' 03 = IP-number
' 04 = IP-number lsb
' 05 = MAC-address
' 06 = MAC-address
' 07 = MAC-address
' 08 = MAC-address
' 09 = MAC-address
' 10 = MAC-address
' 11 = Portnumber
' 12 = Portnumber
' 13 = Length URL-refresh string
' 14 = start of URL-refresh string
' .... upto end of URL-refresh string

'*------begin variable part----------------------------------------------
'
$crystal = 7372800
$regfile = "M32def.dat"
$baud = 57600

' Part that can be used to attach the right ports to the hardware
'
Databus Alias Porta
_databus Alias Pina
Rtldata Alias Porta
Datadirection1 Alias Ddra

'Addrbus Alias Portb
Rtladdr Alias Portb
Datadirection2 Alias Ddrb

Resetport Alias Portd
Eeprom Alias Portd
Ior_pin Alias Portd.6
Iow_pin Alias Portd.7
Datadirection3 Alias Ddrd

Inputport1 Alias Pinc
Inputport2 Alias Portc

Latch Alias Portd.3
Datadirection3 = &HF8                                       ' leave RXD and TXD
'
'*------end variable part - begin fixed part----------------------------------
'
'Configure an interrupt on INT0 on the rising edge
'Config Int0 = Rising

Mcucr.1 = 1
Mcucr.0 = 1

Const Triggerstring = "SEND INFORMATION NOW"                ' 20 characters long

'Configure I2c
Config Scl = Portc.0
Config Sda = Portc.1

Const Pcf8574 = &H40                                        ' LCD's PCF8574
Const Rs = 4
Const E = 7
Config Inputport2 = Input

Inputport2 = &HFC                                           ' pull-ups   leave I2c-lines open...

Dim Myip(4) As Byte At &H64
Dim My_ip As Long At &H64 Overlay
'MAC
Dim Mymac(6) As Byte

' Dimension the variables
Dim Regaddr As Byte
Dim Regdata As Byte
'Ethernet header layout
Dim Hdr_chksum As Long
'Dim Addr As Word
Dim T As Byte
'RTL8019AS
Dim Txstart As Byte
Dim Txlen As Word
Dim Data_l As Byte
Dim Data_h As Byte
Dim Resend As Byte
Dim Rxlen As Word
'variables with overlays
Dim Pageheader(4) As Byte At &HAB
Dim T_enetpacketlenl As Byte At &HAD Overlay
Dim T_enetpacketlenh As Byte At &HAE Overlay
Dim Hulp4 As Word At &HAF
Dim Hulp4h As Byte At &HB0 Overlay
Dim Hulp4l As Byte At &HAF Overlay

Dim I_value16 As Word At &HB1
Dim I_value16h As Byte At &HB2 Overlay
Dim I_value16l As Byte At &HB1 Overlay

Dim Ip_value16 As Word At &HB3
Dim Ip_value16h As Byte At &HB4 Overlay
Dim Ip_value16l As Byte At &HB3 Overlay

Dim Result16 As Word At &HB5
Dim Result16h As Byte At &HB6 Overlay
Dim Result16l As Byte At &HB5 Overlay

Dim My_seqnum As Long At &HB7
Dim My_seqnum0 As Byte At &HB7 Overlay
Dim My_seqnum1 As Byte At &HB8 Overlay
Dim My_seqnum2 As Byte At &HB9 Overlay
Dim My_seqnum3 As Byte At &HBA Overlay

Dim Expected_ack As Long

'don't change the address of Packet(1500) rest is depending on it!!!
Dim Packet(1500) As Byte At &HC0

'Ethernet packet destination
Dim T_enetpacketdest0 As Byte At &HC0 Overlay
Dim T_enetpacketdest1 As Byte At &HC1 Overlay
Dim T_enetpacketdest2 As Byte At &HC2 Overlay
Dim T_enetpacketdest3 As Byte At &HC3 Overlay
Dim T_enetpacketdest4 As Byte At &HC4 Overlay
Dim T_enetpacketdest5 As Byte At &HC5 Overlay
'Ethernet packet source
Dim T_enetpacketsrc0 As Byte At &HC6 Overlay
Dim T_enetpacketsrc1 As Byte At &HC7 Overlay
Dim T_enetpacketsrc2 As Byte At &HC8 Overlay
Dim T_enetpacketsrc3 As Byte At &HC9 Overlay
Dim T_enetpacketsrc4 As Byte At &HCA Overlay
Dim T_enetpacketsrc5 As Byte At &HCB Overlay
'Ethernet packet type
Dim T_enetpackettype As Word At &HCC Overlay
Dim T_arp_hwtype1 As Byte At &HCF Overlay
'Arp
Dim T_arp_prttype1 As Byte At &HD1 Overlay
Dim T_arp_hwlen As Byte At &HD2 Overlay
Dim T_arp_prlen As Byte At &HD3 Overlay
Dim T_arp_op1 As Byte At &HD5 Overlay
'arp source ip address
Dim T_arp_sipaddr0 As Byte At &HDC Overlay
Dim T_arp_sipaddr1 As Byte At &HDD Overlay
Dim T_arp_sipaddr2 As Byte At &HDE Overlay
Dim T_arp_sipaddr3 As Byte At &HDF Overlay
'arp target IP address
Dim T_arp_tipaddr As Long At &HE6 Overlay
'IP header layout IP version and header length
Dim T_ip_vers_len As Byte At &HCE Overlay
'packet length
Dim T_ip_pktlen0 As Byte At &HD0 Overlay
Dim T_ip_pktlen1 As Byte At &HD1 Overlay
'protocol (ICMP=1, TCP=6, UDP=11)
Dim T_ip_proto As Byte At &HD7 Overlay
'header checksum
Dim T_ip_hdr_cksum0 As Byte At &HD8 Overlay
Dim T_ip_hdr_cksum1 As Byte At &HD9 Overlay
Dim T_ip_hdr_cksum As Word At &HD8 Overlay
'IP address of source
Dim T_ip_srcaddr0 As Byte At &HDA Overlay
Dim T_ip_srcaddr1 As Byte At &HDB Overlay
Dim T_ip_srcaddr2 As Byte At &HDC Overlay
Dim T_ip_srcaddr3 As Byte At &HDD Overlay
Dim T_ip_srcaddr As Long At &HDA Overlay
'IP address of destination
Dim T_ip_destaddr0 As Byte At &HDE Overlay
Dim T_ip_destaddr1 As Byte At &HDF Overlay
Dim T_ip_destaddr2 As Byte At &HE0 Overlay
Dim T_ip_destaddr3 As Byte At &HE1 Overlay
Dim T_ip_destaddr As Long At &HDE Overlay
Dim T_icmp_type As Byte At &HE2 Overlay
Dim T_icmp_code As Byte At &HE3 Overlay
Dim T_icmp_cksum0 As Byte At &HE4 Overlay
Dim T_icmp_cksum1 As Byte At &HE5 Overlay
Dim T_icmp_cksum As Word At &HE4 Overlay
Dim Tcp_srcporth As Byte At &HE2 Overlay
Dim Tcp_srcportl As Byte At &HE3 Overlay
Dim Tcp_destporth As Byte At &HE4 Overlay
Dim Tcp_destportl As Byte At &HE5 Overlay
Dim Tcp_seqnum3 As Byte At &HE6 Overlay
Dim Tcp_seqnum2 As Byte At &HE7 Overlay
Dim Tcp_seqnum1 As Byte At &HE8 Overlay
Dim Tcp_seqnum0 As Byte At &HE9 Overlay
Dim Tcp_acknum3 As Byte At &HEA Overlay
Dim Tcp_acknum2 As Byte At &HEB Overlay
Dim Tcp_acknum1 As Byte At &HEC Overlay
Dim Tcp_acknum0 As Byte At &HED Overlay
Dim Tcp_hdr As Byte At &HEE Overlay
Dim Tcp_flags As Byte At &HEF Overlay
Dim Tcp_cksumh As Byte At &HF2 Overlay
Dim Tcp_cksuml As Byte At &HF3 Overlay
Dim Tcp_cksum As Word At &HF2 Overlay

Dim Client_seqnum As Long At &H8E
Dim Client_seqnum0 As Byte At &H8E Overlay
Dim Client_seqnum1 As Byte At &H8F Overlay
Dim Client_seqnum2 As Byte At &H90 Overlay
Dim Client_seqnum3 As Byte At &H91 Overlay

Dim Incoming_ack As Long At &H92
Dim Incoming_ack0 As Byte At &H92 Overlay
Dim Incoming_ack1 As Byte At &H93 Overlay
Dim Incoming_ack2 As Byte At &H94 Overlay
Dim Incoming_ack3 As Byte At &H95 Overlay

Dim Tempstring1 As String * 1
Dim Checktemp As Word
Dim Checksumout As Word
Dim Flags As Byte
Dim Tempstring As String * 10
Dim Byte_read As Byte
Dim I As Integer
Dim Hulp1 As Byte
Dim Hulp2 As Byte
Dim Hulp3 As Word
Dim Hulp5 As Word
Dim I_hulp1 As Word
Dim I_header_length As Word
Dim I_x As Word
Dim Relaystatus As Byte
Dim Tcp_fin As Bit
Dim Tcp_syn As Bit
Dim Tcp_rst As Bit
Dim Tcp_psh As Bit
Dim Tcp_ack As Bit
Dim Tcp_urg As Bit
Dim Tcpdatalen_in As Word
Dim Tcpdatalen_out As Word
Dim Ip_packet_len As Word
Dim Yn As String * 1
Dim Msg_temp As String * 55
Dim Y As Word

'LCD variables
Dim Lcd_t As String * 40
Dim Lcd_tempstr As String * 1
Dim Lcd_temp As Byte
Dim Lcd_x As Byte
Dim Lcd_hulp As Byte
Dim Lcd_h As Byte

Dim I_chksum32 As Long
Dim I_checksum16 As Word
Dim I_temp16 As Word
Dim I_odd As Byte

'UDP header
Dim T_udp_srcport0 As Byte At &HE2 Overlay
Dim T_udp_srcport1 As Byte At &HE3 Overlay
Dim T_udp_destport0 As Byte At &HE4 Overlay
Dim T_udp_destport1 As Byte At &HE5 Overlay
Dim T_udp_destport As Word At &HE4 Overlay
Dim T_udp_len0 As Byte At &HE6 Overlay
Dim T_udp_len1 As Byte At &HE7 Overlay
Dim T_udp_chksum0 As Byte At &HE8 Overlay
Dim T_udp_chksum1 As Byte At &HE9 Overlay
Dim T_udp_chksum As Word At &HE8 Overlay
Dim T_udp_data As Byte At &HEA Overlay

Dim Portpntr As Byte At &HEA Overlay
Dim Portval As String * 4 At &HEB Overlay
Dim Relaypntr As Byte At &HEF Overlay
Dim Relval As String * 4 At &HF0 Overlay
Dim Temppntr As Byte At &HF4 Overlay
Dim Tempval As String * 5 At &HF5 Overlay
Dim Mymacs(6) As String * 2
Dim Triggerstr As String * 20

Declare Sub Write_rtl8019as(byval Regaddr As Byte , Byval Regdata As Byte)
Declare Sub Read_rtl8019as(byval Regaddr As Byte)
Declare Sub Relayon(byval X As Byte)
Declare Sub Relayoff(byval X As Byte)
Declare Sub Getpacket
Declare Sub Setipaddrs
Declare Sub Overrun
Declare Sub Echopacket
Declare Sub Arp
Declare Sub Icmp
Declare Sub Init_rtl8019as
Declare Sub Ip_header_checksum
Declare Sub Icmp_checksum
Declare Sub Status
Declare Sub Udp
Declare Sub Udp_checksum
Declare Sub Tcp
Declare Sub Http
Declare Sub Calculate_length
Declare Sub Assemble_ack
Declare Sub Tcp_checksum
Declare Sub Send_tcp_packet
Declare Sub Setup_packet
Declare Sub Application_code
Declare Sub Tcpseqtomyseq
Declare Sub Incomacqtotcpack
Declare Sub Tcpsyn
Declare Sub Packetshape
Declare Sub Write_dest_mac
Declare Sub Configure
Declare Sub Read_ip
Declare Sub Print_ip
Declare Sub Read_mac
Declare Sub Print_mac
Declare Sub Default_message
Declare Sub Lcd_init
Declare Sub Lcd_char(byval Lcd_c As Byte)
Declare Sub Lcd_txt                                         ' (byval Lcd_t As String)
Declare Sub Lcdhome                                         ' CLS/Home
Declare Sub Firstline                                       ' goto 0/0 of LCD
Declare Sub Secondline                                      ' goto second line of LCD
Declare Sub Lcd_routine1
Declare Sub Lcd_routine2
Declare Sub Lcd_routine3
Declare Sub Lcd_routine4
Declare Sub Lcd_routine5

'IP Protocol types
'icmp
Const Prot_icmp = &H01
'tcp
Const Prot_tcp = &H06
'udp
Const Prot_udp = &H11
Const Synflag = 0
Const Finflag = 1
'Realtek control register offsets. All offsets in Page 0 unless otherwise specified
Const Cr = &H00
Const Pstart = &H01
Const Pstop = &H02
Const Bnry = &H03
Const Tpsr = &H04
Const Tbcr0 = &H05
Const Tbcr1 = &H06
Const Isr = &H07
Const Curr = &H07                                           'page 1
Const Rsar0 = &H08
'Const Crda0 = &H08
Const Rsar1 = &H09
'Const Crdal = &H09
Const Rbcr0 = &H0A
Const Rbcr1 = &H0B
Const Rsr = &H0C
Const Rcr = &H0C
Const Tcr = &H0D
Const Dcr = &H0E
Const Imr = &H0F
Const Rdmaport = &H10
Const Rstport = &H18
'RTL8019AS initial register values
Const Rcrval = &H04
Const Tcrval = &H00
Const Dcrval = &H58
'PXR and OVW interrupt enabled
Const Imrval = &H11
Const Txtstart = &H40
Const Rxstart = &H46
Const Rxstop = &H60
'RTL8019AS ISR Register definitions
Const Rst = &H80
Const Rdc = &H40
Const Ovw = &H10
Const Prx = &H01
Const Msg_initfail = "Init failed"

' Main program
'
Main:
Reset Latch
Datadirection1 = &HFF
Databus = 0                                                 ' put zero's on relays-port
Set Latch
Reset Latch
Relaystatus = 0                                             ' put zero's in the relaystatus byte
Call Lcd_init
Lcd_t = "EIO-board"
Call Lcd_txt
Call Secondline
Lcd_t = "Firmware: 01.00"
Call Lcd_txt
Call Configure
Call Default_message
Call Init_rtl8019as


' Sit and wait for an Interrupt from the RTL8019AS
'
Enable Interrupts
Enable Int0
On Int0 Rtl8019as_interrupt
'start the NIC
Call Write_rtl8019as(cr , &H22)
Do
Loop
End


' Routine to handle an interrupt on the RTL8019AS
'
Rtl8019as_interrupt:
   Disable Int0
   'read the interrupt status register
   Call Read_rtl8019as(isr)
   'if the receive buffer has been overrun
   If Byte_read.4 = 1 Then
      Call Overrun
   End If
   'if the receive buffer holds a good packet
   If Byte_read.0 = 1 Then
      Call Getpacket
   End If
   'make sure the receive buffer ring is empty. If BNRY = CURR, the buffer is empty
   Call Read_rtl8019as(bnry)
   Data_l = Byte_read
   Call Write_rtl8019as(cr , &H62)
   Call Read_rtl8019as(curr)
   Data_h = Byte_read
   Call Write_rtl8019as(cr , &H22)
   'buffer is not empty, get next packet
   If Data_l <> Data_h Then
      Call Getpacket
   End If
   'reset the interrupts bits
   Call Write_rtl8019as(isr , &HFF)
   Call Write_rtl8019as(cr , &H22)
   Enable Int0
Return


' Routine to initialise the RTL8019AS ethernetchip
'
Sub Init_rtl8019as
   Datadirection1 = &H00
   Databus = &HFF
   Datadirection2 = &HFF
   Rtladdr = &H00
   Datadirection3 = &HF8
   Reset Eeprom.5
   Set Iow_pin
   Set Ior_pin
   Set Resetport.4
   Waitms 2
   Reset Resetport.4
   Call Read_rtl8019as(rstport)
   Call Write_rtl8019as(rstport , Byte_read)
   Waitms 10
   'check for good soft reset
   Call Read_rtl8019as(isr)
   If Byte_read.7 = 0 Then
       Print Msg_initfail
   End If
   Call Write_rtl8019as(cr , &H21)
   Waitms 2
   Call Write_rtl8019as(dcr , Dcrval)
   Call Write_rtl8019as(rbcr0 , &H00)
   Call Write_rtl8019as(rbcr1 , &H00)
   Call Write_rtl8019as(rcr , &H04)
   Call Write_rtl8019as(tpsr , Txtstart)
   Call Write_rtl8019as(tcr , &H02)
   Call Write_rtl8019as(pstart , Rxstart)
   Call Write_rtl8019as(bnry , Rxstart)
   Call Write_rtl8019as(pstop , Rxstop)
   Call Write_rtl8019as(cr , &H61)
   Waitms 2
   Call Write_rtl8019as(curr , Rxstart)
   For Hulp1 = 1 To 6
      Call Write_rtl8019as(hulp1 , Mymac(hulp1))
   Next Hulp1
   Call Write_rtl8019as(cr , &H21)
   Call Write_rtl8019as(dcr , Dcrval)
   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(isr , &HFF)
   Call Write_rtl8019as(imr , Imrval)
   Call Write_rtl8019as(tcr , Tcrval)
End Sub


' Routine to handle an overrun
'
Sub Overrun
   Call Read_rtl8019as(cr)
   Data_l = Byte_read
   Call Write_rtl8019as(cr , &H21)
   Waitms 2
   Call Write_rtl8019as(rbcr0 , &H00)
   Call Write_rtl8019as(rbcr1 , &H00)
   Hulp1 = Data_l And &H04
   If Hulp1 <> 0 Then
      Resend = 0
      Else
         If Hulp1 = 0 Then
            Call Read_rtl8019as(isr)
            Data_l = Byte_read
            Hulp1 = Data_l And &H02
            Hulp2 = Data_l And &H08
            Hulp3 = Hulp1 Or Hulp2
               If Hulp3 > 0 Then
                  Resend = 0
                  Else
                  Resend = 1
               End If
         End If
   End If
   Call Write_rtl8019as(tcr , &H02)
   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(bnry , Rxstart)
   Call Write_rtl8019as(cr , &H62)
   Call Write_rtl8019as(curr , Rxstart)
   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(isr , &H10)
   Call Write_rtl8019as(tcr , Tcrval)
End Sub


' Routine to Write to NIC Control register
'
Sub Write_rtl8019as(regaddr , Regdata)
   Rtladdr = Regaddr
   Rtldata = Regdata
   Datadirection1 = &HFF
   nop
   Reset Iow_pin
   nop
   Set Iow_pin
   nop
   Datadirection1 = &H00
   Databus = &HFF
End Sub


' Routine to read from NIC Control register
'
Sub Read_rtl8019as(regaddr)
   Datadirection1 = &H00
   Databus = &HFF
   Rtladdr = Regaddr
   Reset Ior_pin
   nop
   Byte_read = Pina
   nop
   Set Ior_pin
   nop
End Sub


' Routine to execute send packet command to retrieve the packet
'
Sub Getpacket
   Call Write_rtl8019as(cr , &H1A)
   For I = 0 To 4
      Call Read_rtl8019as(rdmaport)
      Pageheader(i + 1) = Byte_read
   Next I
   'watch it. overlay variables
   Result16h = T_enetpacketlenh
   Result16l = T_enetpacketlenl
   Rxlen = Result16
   Hulp5 = Rxlen + 1
   For I = 1 To Hulp5
      Call Read_rtl8019as(rdmaport)
      'dump any bytes that will overrun the receive buffer
      If I < 1500 Then
         Packet(i + 1) = Byte_read
      End If
   Next I
   Hulp1 = Byte_read And Rdc
   If Hulp1 <> 64 Then
      Call Read_rtl8019as(isr)
   End If

   Call Write_rtl8019as(isr , &HFF)

   ' Routine to process an ARP packet
   '
   If T_enetpackettype = &H0608 Then
      If T_arp_hwtype1 = &H01 Then
         If T_arp_prttype1 = &H00 Then
            If T_arp_hwlen = &H06 Then
               If T_arp_prlen = &H04 Then
                  If T_arp_op1 = &H01 Then
                     If My_ip = T_arp_tipaddr Then
                        Call Arp
                     End If
                  End If
               End If
            End If
         End If
      End If
   End If


   ' Routine to go ahead with icmp or udp
   '
   If T_enetpackettype = &H0008 Then
         If T_ip_destaddr = My_ip Then
            Select Case T_ip_proto
               Case Prot_icmp : Call Icmp
               Case Prot_tcp : Call Tcp
               Case Prot_udp : Call Udp
            End Select
         End If
   End If
End Sub


' Routine to handle the source/destination address
'
Sub Setipaddrs
   T_ip_destaddr = T_ip_srcaddr
   'make ethernet module IP address source address
   T_ip_srcaddr = My_ip
   Call Packetshape
   Call Ip_header_checksum
End Sub


' Routine to calculate a IP-header checksum
'
Sub Ip_header_checksum
   Local Ip_x As Byte
   Local Ip_hulp1 As Byte
   Local Ip_chksum32 As Long
   Local Ip_checksum16 As Word
   Local Ip_temp16 As Word
   Local Ip_header_length As Byte
   'calculate the IP header checksum
   T_ip_hdr_cksum = &H00
   Hdr_chksum = 0
   Ip_header_length = T_ip_vers_len And &H0F
   Ip_header_length = 4 * Ip_header_length
   Hulp1 = &H0E + Ip_header_length
   Ip_chksum32 = 0
   For Ip_x = 15 To Hulp1 Step 2
      Ip_value16h = Packet(ip_x)
      Ip_hulp1 = Ip_x + 1
      Ip_value16l = Packet(ip_hulp1)
      Ip_value16 = Not Ip_value16
      Ip_chksum32 = Ip_chksum32 + Ip_value16
   Next Ip_x
   Ip_checksum16 = Ip_chksum32
   Ip_temp16 = Highw(ip_chksum32)
   Ip_checksum16 = Ip_checksum16 + Ip_temp16
   T_ip_hdr_cksum0 = High(ip_checksum16)
   T_ip_hdr_cksum1 = Low(ip_checksum16)
End Sub


' Routine to echo a complete packet
'
Sub Echopacket
   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(tpsr , Txstart)
   Call Write_rtl8019as(rsar0 , &H00)
   Call Write_rtl8019as(rsar1 , &H40)
   Call Write_rtl8019as(isr , &HFF)
   Hulp1 = T_enetpacketlenl - 4
   Call Write_rtl8019as(rbcr0 , Hulp1)
   Call Write_rtl8019as(rbcr1 , T_enetpacketlenh)
   Call Write_rtl8019as(cr , &H12)
   Result16h = T_enetpacketlenh
   Result16l = T_enetpacketlenl
   Result16 = Result16 - 4
   Txlen = Result16
   'write the complete packet to the RTL8019AS from packet(1) to packet(txlen+1)
   Hulp5 = Txlen + 1
   For I = 1 To Hulp5
      Call Write_rtl8019as(rdmaport , Packet(i))
   Next I
   Byte_read = 0
   While Hulp1 <> 0
   Hulp1 = Byte_read And Rdc
   Call Read_rtl8019as(isr)
   Wend
   Hulp1 = T_enetpacketlenl - 4
   Call Write_rtl8019as(tbcr0 , Hulp1)
   Call Write_rtl8019as(tbcr1 , T_enetpacketlenh)
   Call Write_rtl8019as(cr , &H24)
End Sub


' Routine to handle ARP-traffic
'
Sub Arp
   'Start the NIC
   Call Write_rtl8019as(cr , &H22)
   'load beginning page for transmit buffer
   Call Write_rtl8019as(tpsr , Txtstart)
   'set start address for remote DMA operation
   Call Write_rtl8019as(rsar0 , &H00)
   Call Write_rtl8019as(rsar1 , &H40)
   'clear the interrupts
   Call Write_rtl8019as(isr , &HFF)
   'load data byte count for remote DMA
   Call Write_rtl8019as(rbcr0 , &H3C)
   Call Write_rtl8019as(rbcr1 , &H00)
   'do remote write operation
   Call Write_rtl8019as(cr , &H12)
   'write destination MAC address
   Call Write_dest_mac
   'write source address
   For I = 1 To 6
       Call Write_rtl8019as(rdmaport , Mymac(i))
   Next I
   'arp target IP address
   'arp_op1 = packet(&h16)
   Packet(&H16) = &H02
   For I = 0 To 9
      Hulp1 = &HCC + I
      T = Peek(hulp1)
      Call Write_rtl8019as(rdmaport , T)
   Next I
   'write ethernet module mac address
   For I = 1 To 6
      Call Write_rtl8019as(rdmaport , Mymac(i))
   Next I
   'write myip
   For I = 1 To 4
      Call Write_rtl8019as(rdmaport , Myip(i))
   Next I
   'write remote mac address
   Call Write_dest_mac
   'write remote IP address
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr0)
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr1)
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr2)
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr3)
  'write som pad characters to fill out the packet to the minimum length
   For I = 0 To &H11
      Call Write_rtl8019as(rdmaport , &H00)
   Next I
   'make sure the DMA operation has succesfully completed
   Byte_read = 0
   Do
      Hulp1 = Byte_read And Rdc
      Call Read_rtl8019as(isr)
   Loop Until Hulp1 = 0
   'load numbers of bytes to be transmitted
   Call Write_rtl8019as(tbcr0 , &H3C)
   Call Write_rtl8019as(tbcr1 , &H00)
   'send the contents of the transmit buffer onto the network
   Call Write_rtl8019as(cr , &H24)
End Sub


' Routine to handle ICMP-traffic (PING)
'
Sub Icmp
   'set echo reply
   T_icmp_type = &H00
   T_icmp_code = &H00
   'setup the IP-header
   Call Setipaddrs
   Call Icmp_checksum
   Call Echopacket
End Sub


' Routine to calculate a ICMP-checksum
'
Sub Icmp_checksum
   'clear the ICMP checksum
   T_icmp_cksum = &H00
   'calculate the ICMP checksum
   I_header_length = T_ip_pktlen1 - 20
   'I_header_length = I_header_length - 20
   I_odd = I_header_length Mod 2
   '14 for MAC-part
   '20 for IP-header
   'start on 35
   'ip_pktlen = 00 3c (60)
   'icmp-packetlengte = ip_pktlen - ip_header
   I_chksum32 = 0
   'Total packetlength - ip_header - 1
   Hulp4h = T_ip_pktlen0 .
   Hulp4l = T_ip_pktlen1
   Hulp4 = Hulp4 + 13
   For I_x = 35 To Hulp4 Step 2
      I_value16h = Packet(i_x)
      I_hulp1 = I_x + 1
      I_value16l = Packet(i_hulp1)
      I_value16 = Not I_value16
      I_chksum32 = I_chksum32 + I_value16
   Next I_x
   If I_odd = 1 Then
      I_value16h = Packet(i_x)
      I_value16l = 0
      I_value16 = Not I_value16
      I_chksum32 = I_chksum32 + I_value16
   End If
   I_checksum16 = I_chksum32
   I_temp16 = Highw(i_chksum32)
   I_checksum16 = I_checksum16 + I_temp16
   T_icmp_cksum0 = High(i_checksum16)
   T_icmp_cksum1 = Low(i_checksum16)
End Sub

' Routine to handle UDP-traffic
'
Sub Udp
Local Udp_port As Word
Local Udp_porth As Byte
Local Udp_portl As Byte
Readeeprom Udp_porth , 11
Readeeprom Udp_portl , 12
Udp_port = Udp_porth
Shift Udp_port , Left , 8
Udp_port = Udp_port + Udp_portl
Triggerstr = ""
Hulp1 = &HEA
For Hulp2 = 1 To 20
   Hulp3 = Peek(hulp1)
   Triggerstr = Triggerstr + Chr(hulp3)
   Incr Hulp1
Next Hulp2
      'From within a VB-program
      If T_udp_destport = Udp_port Then
            Select Case T_udp_data
               Case &H01 : Call Relayon(1)
               Case &H02 : Call Relayon(2)
               Case &H03 : Call Relayon(3)
               Case &H04 : Call Relayon(4)
               Case &HA1 : Call Relayoff(5)
               Case &HA2 : Call Relayoff(6)
               Case &HA3 : Call Relayoff(7)
               Case &HA4 : Call Relayoff(8)
            End Select
            If Triggerstr = Triggerstring Then
               Call Lcdhome
               Lcd_t = "UDP request#Sending: "
               Call Lcd_txt
               Portpntr = Asc( "P")
               Tempstring = Bin(inputport1)
               Portval = Left(tempstring , 4)
               Lcd_t = "P" + Portval
               Relaypntr = Asc( "R")
               Tempstring = Bin(relaystatus)
               Relval = Right(tempstring , 4)
               Lcd_t = Lcd_t + "R"
               Lcd_t = Lcd_t + Relval
               Call Lcd_txt
               'Build The Ip Header
               Call Setipaddrs
               'swap the UDP source and destinations port
               Swap T_udp_srcport0 , T_udp_destport0
               Swap T_udp_srcport1 , T_udp_destport1
               Call Udp_checksum
               Call Write_rtl8019as(cr , &H22)
               Call Echopacket
            End If
      End If
End Sub

' Routine to calculate the IP-checkum
'
Sub Udp_checksum
    T_udp_chksum = &H00
   'checksum TCP header
   I_chksum32 = 0
   I_value16h = T_ip_srcaddr0
   I_value16l = T_ip_srcaddr1
   I_chksum32 = I_chksum32 + I_value16
   I_value16h = T_ip_srcaddr2
   I_value16l = T_ip_srcaddr3
   I_chksum32 = I_chksum32 + I_value16
   I_value16h = T_ip_destaddr0
   I_value16l = T_ip_destaddr1
   I_chksum32 = I_chksum32 + I_value16
   I_value16h = T_ip_destaddr2
   I_value16l = T_ip_destaddr3
   I_chksum32 = I_chksum32 + I_value16
   'proto
   I_chksum32 = I_chksum32 + T_ip_proto
   'packet length
   I_value16h = T_udp_len0
   I_value16l = T_udp_len1
   I_chksum32 = I_chksum32 + I_value16
   I_odd = T_udp_len1 Mod 2
   Result16h = T_udp_len0
   Result16l = T_udp_len1
   'udp_srcport0 = packet(&h23)
   Hulp1 = &H23
   Hulp2 = &H23 + Result16
   Hulp2 = Hulp2 - 2
   For I_x = Hulp1 To Hulp2 Step 2
      I_value16h = Packet(i_x)
      Hulp3 = I_x + 1
      I_value16l = Packet(hulp3)
      I_chksum32 = I_chksum32 + I_value16
   Next I_x
   If I_odd = 1 Then
      Incr Hulp2
      I_value16h = Packet(hulp2)
      I_value16l = 0
      I_chksum32 = I_chksum32 + I_value16
   End If
   I_checksum16 = Highw(i_chksum32)
   I_checksum16 = I_checksum16 + I_chksum32                 ' only 16 lower bits of i_chksum32 is taken...
   I_checksum16 = Not I_checksum16
   T_udp_chksum0 = High(i_checksum16)
   T_udp_chksum1 = Low(i_checksum16)
End Sub


' Routine to switch on relay X and update status
'
Sub Relayon(x)
Decr X
Relaystatus.x = 1
Call Status
End Sub


' Routine to switch off relay X and update status
'
Sub Relayoff(x)
X = X - 5
Relaystatus.x = 0
Call Status
End Sub


' Routine to switch on/off relay and get the status
'
Sub Status
   Datadirection1 = &HFF
   Databus = Relaystatus
   Set Latch
   Reset Latch
End Sub


' TCP (HTTP)
Sub Tcp
Local Work As Byte

Work = Tcp_flags
Tcp_fin = Work.0
Tcp_syn = Work.1
Tcp_rst = Work.2
Tcp_psh = Work.3
Tcp_ack = Work.4
Tcp_urg = Work.5

If Tcp_destporth = 0 Then
   Select Case Tcp_destportl
      Case 80 : Call Http
   End Select
End If
End Sub


Sub Assemble_ack
Client_seqnum0 = Tcp_seqnum0
Client_seqnum1 = Tcp_seqnum1
Client_seqnum2 = Tcp_seqnum2
Client_seqnum3 = Tcp_seqnum3
Client_seqnum = Client_seqnum + Tcpdatalen_in
Tcp_acknum0 = Client_seqnum0
Tcp_acknum1 = Client_seqnum1
Tcp_acknum2 = Client_seqnum2
Tcp_acknum3 = Client_seqnum3
End Sub


Sub Tcp_checksum
Local Whulp1 As Word
Local Whulp2 As Word
Local Whulp3 As Word
Local Tcp_odd As Byte
Local Tempword As Word
Local Tempword2 As Word
Tcp_cksum = 0
Hdr_chksum = 0
Tempword = T_ip_srcaddr0 * 256
Tempword = Tempword + T_ip_srcaddr1
Hdr_chksum = Tempword
Tempword = T_ip_srcaddr2 * 256
Tempword = Tempword + T_ip_srcaddr3
Hdr_chksum = Hdr_chksum + Tempword
Tempword = T_ip_destaddr0 * 256
Tempword = Tempword + T_ip_destaddr1
Hdr_chksum = Hdr_chksum + Tempword
Tempword = T_ip_destaddr2 * 256
Tempword = Tempword + T_ip_destaddr3
Hdr_chksum = Hdr_chksum + Tempword
Hdr_chksum = Hdr_chksum + T_ip_proto
Tempword = T_ip_pktlen0 * 256
Tempword = Tempword + T_ip_pktlen1
Tempword2 = T_ip_vers_len And &H0F
Tempword2 = Tempword2 * 4
Tcp_odd = Tempword Mod 2
Hdr_chksum = Hdr_chksum + Tempword
Hdr_chksum = Hdr_chksum - Tempword2

Whulp2 = Tempword - 20
Whulp2 = Whulp2 + &H23
Whulp2 = Whulp2 - 2

For Whulp1 = &H23 To Whulp2 Step 2
Tempword = Packet(whulp1) * 256
Whulp3 = Whulp1 + 1
Tempword = Tempword + Packet(whulp3)
Hdr_chksum = Hdr_chksum + Tempword
Next Whulp1

If Tcp_odd = 1 Then
   Incr Whulp2
   Tempword = Packet(whulp1) * 256
   Hdr_chksum = Hdr_chksum + Tempword
End If

Tempword = Highw(hdr_chksum)
Checktemp = Hdr_chksum
Checksumout = Checktemp + Tempword
Checksumout = Not Checksumout
Tcp_cksumh = High(checksumout)
Tcp_cksuml = Low(checksumout)
End Sub


Sub Calculate_length
Result16h = T_ip_pktlen0
Result16l = T_ip_pktlen1
'
' calculate IP header length
' MSN is version (IPv4)
' LSN is length
Hulp1 = T_ip_vers_len And &H0F
Hulp1 = Hulp1 * 4
' calculate TCP header length
' MSN is length / 4
Hulp2 = Tcp_hdr And &HF0
Shift Hulp2 , Right , 4
Hulp2 = Hulp2 * 4
Tcpdatalen_in = Result16 - Hulp1
Tcpdatalen_in = Tcpdatalen_in - Hulp2
End Sub

' Send the TCP-packet, a bit different then echopacket
Sub Send_tcp_packet
   Ip_packet_len = 40 + Tcpdatalen_out
   T_ip_pktlen1 = Low(ip_packet_len)
   T_ip_pktlen0 = High(ip_packet_len)
   Call Setup_packet
   Swap Tcp_srcporth , Tcp_destporth
   Swap Tcp_srcportl , Tcp_destportl
   Call Assemble_ack
   Call Tcpseqtomyseq
   Tcp_flags = 0
   'fin_out
   Set Tcp_flags.0                                          ' piggyback FIN onto the page date
   'ack_out
   Set Tcp_flags.4
   If Flags.finflag = 1 Then
      'fin_out
      Set Tcp_flags.0
      'clr_finflag
      Reset Flags.finflag
   End If
   Call Tcp_checksum

   Txlen = Ip_packet_len + 14
   If Txlen < 60 Then
      Txlen = 60
   End If

   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(tpsr , Txstart)
   Call Write_rtl8019as(rsar0 , &H00)
   Call Write_rtl8019as(rsar1 , &H40)
   Call Write_rtl8019as(isr , &HFF)
   Hulp1 = Low(txlen)
   Call Write_rtl8019as(rbcr0 , Hulp1)
   Hulp1 = High(txlen)
   Call Write_rtl8019as(rbcr1 , Hulp1)
   Call Write_rtl8019as(cr , &H12)

   For I = 1 To Txlen
      Call Write_rtl8019as(rdmaport , Packet(i))
   Next

   'make sure the DMA operation has succesfully completed
   Byte_read = 0
   Do
      Hulp1 = Byte_read And Rdc
      Call Read_rtl8019as(isr)
   Loop Until Hulp1 = 0

   Hulp1 = Low(txlen)
   Call Write_rtl8019as(tbcr0 , Hulp1)
   Hulp1 = High(txlen)
   Call Write_rtl8019as(tbcr1 , Hulp1)
   Call Write_rtl8019as(cr , &H24)

 End Sub


Sub Setup_packet
'Move IP source address to destination address
T_ip_destaddr = T_ip_srcaddr
'Make ethernet module IP address source address
T_ip_srcaddr = My_ip
'Move hardware source address to destinatin address
Call Packetshape
Call Ip_header_checksum
End Sub

Sub Http
Local Msg_temp2 As String * 10
Local Templong1 As Long
Local Tempword3 As Word
Call Calculate_length
   ' If an ACK is received and the destination port address is valid
   ' and no data is in the packet

If Tcp_ack = 1 Then
         If Tcpdatalen_in = 0 Then
          Call Incomacqtotcpack
            If Flags.synflag = 1 Then
               Reset Flags.synflag
               My_seqnum = Incoming_ack
                 Tempword3 = &H37
                 Call Lcdhome
                 Lcd_t = "HTTP request#Updating webpage"
                 Call Lcd_txt
                 Restore Htmlcode
                 Do
                    Read Msg_temp
                    Msg_temp2 = Right(msg_temp , 8)
                    If Msg_temp2 = "endblock" Then
                       Exit Do
                    End If
                    If Msg_temp2 = "get-ipnr" Then
                       Readeeprom Hulp1 , 13
                       If Hulp1 = &HFF Then
                           Msg_temp = "http://" + Str(myip(1))
                           Msg_temp = Msg_temp + "." + Str(myip(2))
                           Msg_temp = Msg_temp + "." + Str(myip(3))
                           Msg_temp = Msg_temp + "." + Str(myip(4))
                           Else
                           Msg_temp = ""
                           For Y = 1 To Hulp1
                               Hulp3 = Y + 13
                               Readeeprom Hulp2 , Hulp3
                               Msg_temp = Msg_temp + Chr(hulp2)
                           Next Y
                       End If
                    End If
                   If Msg_temp2 = "get-info" Then
                              If Inputport1.4 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Inputport1.5 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Inputport1.6 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Inputport1.7 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.0 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.1 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.2 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.3 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                    Else
                          For Y = 1 To Len(msg_temp)
                            Tempstring1 = Mid(msg_temp , Y , 1)
                            Packet(tempword3) = Asc(tempstring1)
                            Incr Tempword3
                          Next Y
                    End If
                Loop
                Tcpdatalen_out = Tempword3 - 55             'minus headerlength
               ' expect to get an acknowledgment of the message
               Expected_ack = My_seqnum + Tcpdatalen_out

               ' send the TCP/IP packet
               Call Send_tcp_packet
          End If
     End If
End If


 ' This code segment processes the incoming SYN from the Tenet client
' and sends back the initial sequence number (ISN) and acknowledges
' the incoming SYN packet
If Tcp_syn = 1 Then
   Call Tcpsyn
End If

If Tcp_fin = 1 Then
      Set Flags.finflag
      Incr Tcpdatalen_in
      Call Incomacqtotcpack
      If Incoming_ack <= Expected_ack Then
         Templong1 = Expected_ack - Incoming_ack
         My_seqnum = Expected_ack - Templong1
      End If
      Expected_ack = My_seqnum + Tcpdatalen_out
      Call Send_tcp_packet
End If

If Tcp_psh = 1 Then
                 Tempstring1 = Chr(packet(60))
                 If Tempstring1 = "R" Then
                     Hulp1 = Val(packet(61))
                     Select Case Hulp1
                        Case 1 To 4 : Call Relayon(hulp1)
                        Case 5 To 8 : Call Relayoff(hulp1)
                     End Select
                 End If
End If
End Sub

Sub Tcpseqtomyseq
Tcp_seqnum0 = My_seqnum0
Tcp_seqnum1 = My_seqnum1
Tcp_seqnum2 = My_seqnum2
Tcp_seqnum3 = My_seqnum3
End Sub

Sub Incomacqtotcpack
Incoming_ack0 = Tcp_acknum0
Incoming_ack1 = Tcp_acknum1
Incoming_ack2 = Tcp_acknum2
Incoming_ack3 = Tcp_acknum3
End Sub

Sub Tcpsyn
   Tcpdatalen_in = 1
   Set Flags.synflag
   Call Setup_packet
   Swap Tcp_srcportl , Tcp_destportl
   Swap Tcp_srcporth , Tcp_destporth
   Call Assemble_ack
   Call Tcpseqtomyseq
   Tcp_flags = 0
   Set Tcp_flags.1
   Set Tcp_flags.4
   Call Tcp_checksum
   Call Echopacket
End Sub


Sub Packetshape
'move hardware source address to destination address
T_enetpacketdest0 = T_enetpacketsrc0
T_enetpacketdest1 = T_enetpacketsrc1
T_enetpacketdest2 = T_enetpacketsrc2
T_enetpacketdest3 = T_enetpacketsrc3
T_enetpacketdest4 = T_enetpacketsrc4
T_enetpacketdest5 = T_enetpacketsrc5
'   'Make ethernet module mac address the source address
T_enetpacketsrc0 = Mymac(1)
T_enetpacketsrc1 = Mymac(2)
T_enetpacketsrc2 = Mymac(3)
T_enetpacketsrc3 = Mymac(4)
T_enetpacketsrc4 = Mymac(5)
T_enetpacketsrc5 = Mymac(6)
End Sub


Sub Write_dest_mac
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc0)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc1)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc2)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc3)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc4)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc5)
End Sub


' Routine to get a configuration-screen on the RS232 port
'
Sub Configure
Local Adr As Word
Local Row As Byte
Local Ipnr As String * 15
Local Dot1 As Byte
Local Dot2 As Byte
Local Dot3 As Byte
Local Dot4 As Byte
Local Dot5 As Byte
Local Iptemp As String * 1
Local Ippart As String * 3
Local Macadr As String * 20
Print Chr(&H1b) ; "[2J";                                    ' ANSI goto 0/0
Print
Print "Atmega32 Loader Version 1.0"
Print
Print
Print "Present configuration:"
Print
Print "Network:"
Print
Print "IP-number: ";
Call Read_ip
Call Print_ip
Call Read_mac
Print
Print "MAC-address: ";
Print Hex(mymac(1)) ; "-" ; Hex(mymac(2)) ; "-" ; Hex(mymac(3)) ; "-" ; Hex(mymac(4)) ; "-" ; Hex(mymac(5)) ; "-" ; Hex(mymac(6))
Print
Print
Print "Press 'y' to get into configuration mode"

Test:
Incr Hulp3
If Hulp3 = 65000 Then
   Incr Hulp1
   Hulp3 = 0
End If
If Hulp1 = 25 Then
   Goto Noresponse
End If
sbis USR,7
rjmp test

Configuremode:
Call Lcd_init
Lcd_t = "Configure-mode"
Call Lcd_txt
Print Chr(&H1b) ; "[2J";                                    ' ANSI goto 0/0 Print
Print "Configure mode:"
Print
Print "Network:"
Print
Print "IP-number: ";
Call Print_ip
Input "Change IP-number (y/n) " , Yn
If Yn = "y" Then
   Print
   Print "Input IP-numbers as decimals, seperated by a dot (like 192.168.1.106)"
   Print
   Input Ipnr
      Hulp1 = Len(ipnr)
   For Hulp2 = 1 To Hulp1
      Incr Dot1
      Iptemp = Mid(ipnr , Hulp2 , 1)
      If Iptemp = "." Then
         Exit For
      End If
   Next
   Dot2 = Dot1
   Incr Dot1
   For Hulp2 = Dot1 To Hulp1
      Incr Dot2
      Iptemp = Mid(ipnr , Hulp2 , 1)
      If Iptemp = "." Then
         Exit For
      End If
   Next
   Dot3 = Dot2
   Incr Dot2
   For Hulp2 = Dot2 To Hulp1
      Incr Dot3
      Iptemp = Mid(ipnr , Hulp2 , 1)
      If Iptemp = "." Then
         Exit For
      End If
   Next
   Incr Dot3

   Ippart = Mid(ipnr , 1 , Dot1)
   Myip(1) = Val(ippart)
   Hulp1 = Dot2 - Dot1
   Ippart = Mid(ipnr , Dot1 , Hulp1)
   Myip(2) = Val(ippart)
   Hulp1 = Dot3 - Dot2
   Ippart = Mid(ipnr , Dot2 , Hulp1)
   Myip(3) = Val(ippart)
   Ippart = Mid(ipnr , Dot3)
   Myip(4) = Val(ippart)

   Print
   Print "New IP-number: ";
   Call Print_ip
   Print
   Input "Accept IP-number (y/n) " , Yn
   If Yn = "y" Then
      Writeeeprom Myip(1) , 1 : Writeeeprom Myip(2) , 2
      Writeeeprom Myip(3) , 3 : Writeeeprom Myip(4) , 4
    End If
    Print
    Print "IP-number: ";
    Call Read_ip
    Call Print_ip
End If
Print
Input "Change MAC-address (y/n) " , Yn
If Yn = "y" Then

Mac:
Print
Print "Input MAC-address in hexadecimals, seperated by a - (like 00-34-35-36-37-48)"
Print
Input Macadr
If Len(macadr) <> 17 Then Goto Mac

Mymacs(1) = Mid(macadr , 1 , 2)
Mymacs(2) = Mid(macadr , 4 , 2)
Mymacs(3) = Mid(macadr , 7 , 2)
Mymacs(4) = Mid(macadr , 10 , 2)
Mymacs(5) = Mid(macadr , 13 , 2)
Mymacs(6) = Mid(macadr , 16 , 2)

Mymac(1) = Hexval(mymacs(1))
Mymac(2) = Hexval(mymacs(2))
Mymac(3) = Hexval(mymacs(3))
Mymac(4) = Hexval(mymacs(4))
Mymac(5) = Hexval(mymacs(5))
Mymac(6) = Hexval(mymacs(6))

   Print
   Print "New MAC-address: ";
   Call Print_mac
   Print
   Input "Accept MAC-address (y/n) " , Yn
   If Yn = "y" Then
      Writeeeprom Mymac(1) , 5 : Writeeeprom Mymac(2) , 6
      Writeeeprom Mymac(3) , 7 : Writeeeprom Mymac(4) , 8
      Writeeeprom Mymac(5) , 9 : Writeeeprom Mymac(6) , 10
    End If
    Print
    Print "MAC-address: ";
    Call Read_mac
    Call Print_mac
End If
Print
Input "Would you like to use it's own IP-number as refresh-URL (y/n) " , Yn
If Yn = "y" Then
      Hulp1 = 255
      Writeeeprom Hulp1 , 13
   Else
      Print
      Input "Would you like to have another refresh-URL (y/n) " , Yn
      If Yn = "y" Then
        Input "Type the complete refresh URL " , Msg_temp
        Print
        Print "Refresh URL " ; Msg_temp
        Print
        Input "Accept Refresh-URL (y/n) " , Yn
        If Yn = "y" Then
             Hulp2 = Len(msg_temp)
             Writeeeprom Hulp2 , 13                         ' write length of Refresh URL
             For Y = 1 To Hulp2
                Hulp1 = Y + 13
                Tempstring1 = Mid(msg_temp , Y , 1)
                Hulp2 = Asc(tempstring1)
                Writeeeprom Hulp2 , Hulp1
             Next Y
        End If
      End If
End If

Print
Hulp4 = 5000
Writeeeprom Hulp4h , 12                                     ' &h1388 = 5000 dec = 19 high, 136 low.
Writeeeprom Hulp4l , 11

Input "Would you like to change to UDP Portnumber. It's default is 5000 (y/n) " , Yn
If Yn = "y" Then
   Print
   Input "Type the portnumber < 65536 as decimal " , Hulp4
   Print
   Print "Portnumber UDP " ; Hulp4
   Print
   Input "Accept Portnumber UDP (y/n) " , Yn
   If Yn = "y" Then
      Writeeeprom Hulp4h , 12
      Writeeeprom Hulp4l , 11
   End If
End If
Print

Print Chr(&H1b) ; "[2J";                                    ' ANSI goto 0/0 Print
Input "Would you like to see all devices on the I2c-bus (y/n) " , Yn
If Yn = "y" Then
   Print "I2c-device locator   1 = no device     0 = device"
   Print
   Print "       0    2    4    6    8    A    C    E"
   Print " 0000 ";
   For Adr = 0 To 254 Step 2
      Row = Adr Mod 16                                      ' addresses
      If Row = 0 And Adr > 0 Then
         Print                                              ' end of line?
         Print " " ; Hex(adr) ; " ";
      End If
      I2cstart                                              ' generate start
      I2cwbyte Adr
      Print " " ; Err ; "   ";                              ' 1 no device, 0 device
      I2cstop
   Next Adr
   Print
End If
Print
Input "Any key to continue...." , Yn
Print

Noresponse:
Print Chr(&H1b) ; "[2J";                                    ' ANSI goto 0/0
Print "Summary:"
Print
Print "Network:"
Print
Print "IP-number  : " ; Myip(1) ; "." ; Myip(2) ; "." ; Myip(3) ; "." ; Myip(4)
Print
Print "Mac-address: " ; Hex(mymac(1)) ; "-" ; Hex(mymac(2)) ; "-" ; Hex(mymac(3)) ; "-" ; Hex(mymac(4)) ; "-" ; Hex(mymac(5)) ; "-" ; Hex(mymac(6))
Print
Print "URL-refresh: ";
Readeeprom Hulp1 , 13
If Hulp1 = &HFF Then
      Print "http://" ; Myip(1) ; "." ; Myip(2) ; "." ; Myip(3) ; "." ; Myip(4)
   Else
      Msg_temp = ""
      For Y = 1 To Hulp1
         Hulp3 = Y + 13
         Readeeprom Hulp2 , Hulp3
         Msg_temp = Msg_temp + Chr(hulp2)
      Next Y
      Print Msg_temp
End If
Print
Print "UDP-port   : ";
Readeeprom Hulp4h , 12
Readeeprom Hulp4l , 11
Print Hulp4
Print
Print
Print "Running..."
End Sub


' Routine to read the IP-numbers from the EEPROM
'
Sub Read_ip
   Readeeprom Myip(1) , 1 : Readeeprom Myip(2) , 2
   Readeeprom Myip(3) , 3 : Readeeprom Myip(4) , 4
End Sub


' Routine to print the IP-number
'
Sub Print_ip
   Print Myip(1) ; "." ; Myip(2) ; "." ; Myip(3) ; "." ; Myip(4)
End Sub

' Routine to read the MAC-address from the EEPROM
'
Sub Read_mac
   Readeeprom Mymac(1) , 5 : Readeeprom Mymac(2) , 6
   Readeeprom Mymac(3) , 7 : Readeeprom Mymac(4) , 8
   Readeeprom Mymac(5) , 9 : Readeeprom Mymac(6) , 10
End Sub


' Routine to print the MAC-address
'
Sub Print_mac
   Print Hex(mymac(1)) ; "-" ; Hex(mymac(2)) ; "-" ; Hex(mymac(3)) ; "-" ; Hex(mymac(4)) ; "-" ; Hex(mymac(5)) ; "-" ; Hex(mymac(6))
End Sub


' Routine to send a default-message to the LCD
'
Sub Default_message
Call Lcd_init
Lcd_t = "Embedded WEB-server#IP: "
Call Lcd_txt
Call Read_ip
Lcd_t = Str(myip(1)) + "." + Str(myip(2)) + "." + Str(myip(3)) + "." + Str(myip(4))
Call Lcd_txt
End Sub


' Subroutine to initialise the LCD-display
Sub Lcd_init
Waitms 15
I2csend Pcf8574 , &B00000011
I2csend Pcf8574 , &B10000011
I2csend Pcf8574 , &B00000011
Waitms 4
I2csend Pcf8574 , &B00000011
I2csend Pcf8574 , &B10000011
I2csend Pcf8574 , &B00000011
Waitms 1
I2csend Pcf8574 , &B00000011
I2csend Pcf8574 , &B10000011
I2csend Pcf8574 , &B00000011
Waitms 4
I2csend Pcf8574 , &B00000010
I2csend Pcf8574 , &B10000010
I2csend Pcf8574 , &B00000010
Waitms 1
I2csend Pcf8574 , &B00000010
I2csend Pcf8574 , &B10000010
I2csend Pcf8574 , &B00000010
I2csend Pcf8574 , &B00001000
I2csend Pcf8574 , &B10001000
I2csend Pcf8574 , &B00001000
Waitms 1
I2csend Pcf8574 , &B00000000
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
I2csend Pcf8574 , &B00001000
I2csend Pcf8574 , &B10001000
I2csend Pcf8574 , &B00001000
Waitms 1
I2csend Pcf8574 , &B00000000
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
I2csend Pcf8574 , &B00001100
I2csend Pcf8574 , &B10001100
I2csend Pcf8574 , &B00001100
Waitms 1
I2csend Pcf8574 , &B00000000
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
I2csend Pcf8574 , &B00000001
I2csend Pcf8574 , &B10000001
I2csend Pcf8574 , &B00000001
Waitms 1
End Sub


' Subroutine to send a character to the LCD-display
Sub Lcd_char(lcd_c As Byte)
If Lcd_c = 42 Then                                          '* CLS/HOME
      Call Lcdhome
   Elseif Lcd_c = 35 Then                                   '# second line
      Call Secondline
   Else
      Lcd_temp = Lcd_c And &HF0
      Rotate Lcd_temp , Right , 4
      I2csend Pcf8574 , Lcd_temp
      Set Lcd_temp.e
      Set Lcd_temp.rs
      I2csend Pcf8574 , Lcd_temp
      Reset Lcd_temp.e
      Reset Lcd_temp.rs
      I2csend Pcf8574 , Lcd_temp
      Lcd_temp = Lcd_c And &H0F
      I2csend Pcf8574 , Lcd_temp
      Set Lcd_temp.e
      Set Lcd_temp.rs
      I2csend Pcf8574 , Lcd_temp
      Reset Lcd_temp.e
      Reset Lcd_temp.rs
      I2csend Pcf8574 , Lcd_temp
   End If
End Sub


' Subroutine to send a string to the LCD-display
Sub Lcd_txt
Lcd_hulp = Len(lcd_t)
For Lcd_x = 1 To Lcd_hulp
   Lcd_tempstr = Mid(lcd_t , Lcd_x , 1)
   Lcd_temp = Asc(lcd_tempstr)
   Call Lcd_char(lcd_temp)
Next Lcd_x
End Sub


Sub Lcdhome
I2csend Pcf8574 , &B00000000
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
Waitms 2
I2csend Pcf8574 , &B00000001
I2csend Pcf8574 , &B10000001
I2csend Pcf8574 , &B00000001
Waitms 2
End Sub


Sub Secondline
Call Firstline
For Lcd_h = 1 To 40
   I2csend Pcf8574 , &B00000001
   I2csend Pcf8574 , &B10000001
   I2csend Pcf8574 , &B00000001
   Waitms 2
   I2csend Pcf8574 , &B00000100
   I2csend Pcf8574 , &B10000100
   I2csend Pcf8574 , &B00000100
   Waitms 2
Next Lcd_h
End Sub


Sub Firstline
   I2csend Pcf8574 , &B00000000
   I2csend Pcf8574 , &B10000000
   I2csend Pcf8574 , &B00000000
   Waitms 2
   I2csend Pcf8574 , &B00000010
   I2csend Pcf8574 , &B10000010
   I2csend Pcf8574 , &B00000010
   Waitms 2
End Sub


'************


Htmlcode:
Data "HTTP/1.0 200 OK" , &H0D , &H0A
Data "Content-type: text/html" , &H0D , &H0A , &H0D , &H0A
Data "<html><head><meta http-equiv=" , &H22 , "Refresh" , &H22 , " CONTENT=" , &H22 , "9;URL="

Data "get-ipnr"

Data &H22 , ">"
Data "<meta http-equiv=" , &H22 , "Pragma" , &H22 , " Content=" , &H22 , "no cache" , &H22 , ">"
Data "<title>Ethernet I/O board</title></head>"
Data "<body style=" , &H22 , "font-family: Verdana; font-size: 8pt; "
Data "font-weight: Bold" , &H22 , " link=" , &H22 , "#000000" , &H22 , " vlink=" , &H22
Data "#000000" , &H22 , " alink=" , &H22 , "#000000" , &H22 , ">"
Data "<table border=" , &H22 , "10" , &H22 , " width=" , &H22 , "600" , &H22
Data " bordercolor=" , &H22 , "green" , &H22 , " height=" , &H22 , "225" , &H22
Data " cellspacing=" , &H22 , "12" , &H22 , "><tr>"
Data "get-info"
Data "<tr><tr>"
Data "<td><b>Input 1</td>"
Data "<td><b>Input 2</td>"
Data "<td><b>Input 3</td>"
Data "<td><b>Input 4</td>"
Data "<td><b>Relay 1</td>"
Data "<td><b>Relay 2</td>"
Data "<td><b>Relay 3</td>"
Data "<td><b>Relay 4</td>"
Data "</tr><tr><td height=" , &H22 , "100" , &H22
Data " colspan=" , &H22 , "4" , &H22 , " rowspan=" , &H22 , "2" , &H22 , " bordercolor=" , &H22
Data "white" , &H22 , " valign=" , &H22 , "bottom" , &H22 , ">"
Data "<p><b><font size=" , &H22 , "4" , &H22
Data " color=" , &H22 , "green" , &H22 , ">Ethernet I/O board"
Data "</font></b></p>"
Data "</td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R1" , &H22 , "><b>on</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R2" , &H22 , "><b>on</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R3" , &H22 , "><b>on</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R4" , &H22 , "><b>on</a></td>"
Data "</tr><tr><td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R5" , &H22 , "><b>off</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R6" , &H22 , "><b>off</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R7" , &H22 , "><b>off</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R8" , &H22 , "><b>off</a></td>"
Data "</tr></table></body></html>" , &H0D , &H0A
Data "endblock"
